package com.wx.sys.shiro;

import java.util.List;

import javax.annotation.PostConstruct;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import com.wx.base.util.Constants;
import com.wx.base.util.UserUtil;
import com.wx.base.util.cache.Wx_sys_user_cache;
import com.wx.sys.entity.Wx_sys_user;

/**
 * 自定义realm进行数据源配置
 * 
 * @author lenovo
 *
 */
public class MyRealm extends AuthorizingRealm {
	/**
	 * 只有需要验证权限时才会调用, 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用.在配有缓存的情况下，只加载一次.
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		String loginName = SecurityUtils.getSubject().getPrincipal().toString();
		if (loginName != null) {
			SimpleAuthorizationInfo info = (SimpleAuthorizationInfo) SecurityUtils.getSubject().getSession().getAttribute("user_permissions");
			if (info != null) {
				return info;
			}
			List<String> persions = UserUtil.getUserStringPermission(loginName);
			info = new SimpleAuthorizationInfo();
			info.addStringPermissions(persions);
			return info;
		}
		return null;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
		String username = (String) token.getPrincipal();
		Wx_sys_user wx_sys_user = Wx_sys_user_cache.getCache(username);
		if (wx_sys_user == null) {
			throw new UnknownAccountException();// 没找到帐号;
		} else {
			SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(wx_sys_user, wx_sys_user.getUserpwd(),
					ByteSource.Util.bytes(wx_sys_user.getUsername().toLowerCase()), getName());
			Session session = SecurityUtils.getSubject().getSession();
			session.setAttribute("userSession", wx_sys_user);
			session.setAttribute("userSessionId", wx_sys_user.getUsername());
			return info;
		}
	}

	/**
	 * 更新用户授权信息缓存.
	 */
	public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
		super.clearCachedAuthorizationInfo(principals);
	}

	/**
	 * 更新用户信息缓存.
	 */
	public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
		super.clearCachedAuthenticationInfo(principals);
	}

	/**
	 * 清除用户授权信息缓存.
	 */
	public void clearAllCachedAuthorizationInfo() {
		getAuthorizationCache().clear();
	}

	/**
	 * 清除用户信息缓存.
	 */
	public void clearAllCachedAuthenticationInfo() {
		getAuthenticationCache().clear();
	}

	/**
	 * 清空所有缓存
	 */
	public void clearCache(PrincipalCollection principals) {
		super.clearCache(principals);
	}

	/**
	 * 清空所有认证缓存
	 */
	public void clearAllCache() {
		clearAllCachedAuthenticationInfo();
		clearAllCachedAuthorizationInfo();
	}

	/**
	 * 设定密码校验的Hash算法与迭代次数
	 */
	@PostConstruct
	public void initCredentialsMatcher() {
		HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(Constants.PASSWORD_TYPE);
		matcher.setHashIterations(2);
		setCredentialsMatcher(matcher);
		setAuthenticationCachingEnabled(false);
		setCachingEnabled(false);
	}

}
